import 'package:sqflite/sqflite.dart';
import 'package:flutter/foundation.dart';
import 'package:moonmate/services/database_helper.dart';

// 模式类型枚举
enum AppMode {
  period,     // 经期模式
  pregnancyPrep,  // 备孕模式
  pregnancy,  // 孕期模式
  childcare   // 育儿模式
}

// 基础服务类，作为所有模式服务的基类
class BaseModelService {
  final DatabaseHelper _dbHelper = DatabaseHelper.instance;
  final DataValidationService _validationService = DataValidationService();
  final ModelConversionService _modelConversionService = ModelConversionService();
  int currentUserId = 1; // 默认用户ID

  BaseModelService({this.currentUserId = 1});

  DatabaseHelper get dbHelper => _dbHelper;
  
  // 获取验证服务
  DataValidationService get validationService => _validationService;
  
  // 获取模型转换服务
  ModelConversionService get modelConversionService => _modelConversionService;
  
  // 通用数据操作方法（在子类中可直接使用）
  
  // 查询模型列表
  Future<List<T>> queryModels<T>(
      String tableName,
      T Function(Map<String, dynamic>) factoryMethod,
      {Map<String, dynamic>? where,
      String? orderBy,
      int? limit,
      int? offset
      }) async {
    try {
      final maps = await _dbHelper.queryRows(
        tableName,
        where: where,
        orderBy: orderBy,
      );
      return _modelConversionService.mapsToModels(maps, factoryMethod);
    } catch (e) {
      debugPrint('Error querying models from $tableName: $e');
      return [];
    }
  }
  
  // 插入模型
  Future<int> insertModel<T>(
      String tableName,
      T model,
      Map<String, dynamic> Function(T) toMapMethod) async {
    try {
      final map = _modelConversionService.modelToMap(model, toMapMethod);
      return await _dbHelper.insert(tableName, map);
    } catch (e) {
      debugPrint('Error inserting model into $tableName: $e');
      return -1;
    }
  }
  
  // 更新模型
  Future<int> updateModel(
      String tableName,
      Map<String, dynamic> model,
      Map<String, dynamic> where) async {
    try {
      return await _dbHelper.updateWhere(
        tableName,
        model,
        where,
      );
    } catch (e) {
      debugPrint('Error updating model in $tableName: $e');
      return 0;
    }
  }
  
  // 删除模型
  Future<int> deleteModel(
      String tableName,
      Map<String, dynamic> where) async {
    try {
      return await _dbHelper.deleteWhere(
        tableName,
        where,
      );
    } catch (e) {
      debugPrint('Error deleting model from $tableName: $e');
      return 0;
    }
  }
  
  // 切换用户
  void setCurrentUser(int userId) {
    currentUserId = userId;
  }

  // 获取当前模式数据摘要（用于仪表盘）
  Future<Map<String, dynamic>> getSummaryData() async {
    // 子类需要重写此方法
    return {};
  }

  // 数据统计方法
  Future<Map<String, dynamic>> getStatistics({required String startDate, required String endDate}) async {
    // 子类需要重写此方法
    return {};
  }
}

// 跨模式数据服务类
class CrossModelService {
  final DatabaseHelper _dbHelper = DatabaseHelper.instance;
  late int currentUserId;
  final DataValidationService _validationService = DataValidationService();
  final ModelConversionService _modelConversionService = ModelConversionService();

  CrossModelService({int userId = 1}) {
    currentUserId = userId;
  }

  // 获取验证服务
  DataValidationService get validationService => _validationService;
  
  // 获取模型转换服务
  ModelConversionService get modelConversionService => _modelConversionService;
  
  // 通用数据操作辅助方法
  
  // 通用查询方法，支持模型转换
  Future<List<T>> queryModels<T>(
      String tableName,
      T Function(Map<String, dynamic>) factoryMethod,
      {Map<String, dynamic>? where,
      String? orderBy,
      int? limit,
      int? offset
      }) async {
    try {
      final maps = await _dbHelper.queryRows(
        tableName,
        where: where,
        orderBy: orderBy,
      );
      return _modelConversionService.mapsToModels(maps, factoryMethod);
    } catch (e) {
      debugPrint('Error querying models from $tableName: $e');
      return [];
    }
  }
  
  // 通用插入方法，支持模型转换
  Future<int> insertModel<T>(
      String tableName,
      T model,
      Map<String, dynamic> Function(T) toMapMethod) async {
    try {
      final map = _modelConversionService.modelToMap(model, toMapMethod);
      return await _dbHelper.insert(tableName, map);
    } catch (e) {
      debugPrint('Error inserting model into $tableName: $e');
      return -1;
    }
  }
  
  // 通用更新方法，支持模型转换
  Future<int> updateModel<T>(
      String tableName,
      T model,
      Map<String, dynamic> Function(T) toMapMethod,
      Map<String, dynamic> where) async {
    try {
      final map = _modelConversionService.modelToMap(model, toMapMethod);
      return await _dbHelper.updateWhere(
        tableName,
        map,
        where,
      );
    } catch (e) {
      debugPrint('Error updating model in $tableName: $e');
      return 0;
    }
  }
  
  // 通用删除方法
  Future<int> deleteModel(
      String tableName,
      Map<String, dynamic> where) async {
    try {
      return await _dbHelper.deleteWhere(
        tableName,
        where,
      );
    } catch (e) {
      debugPrint('Error deleting model from $tableName: $e');
      return 0;
    }
  }

  // 切换应用模式
  Future<bool> switchAppMode(String mode) async {
    try {
      await _dbHelper.updateUserMode(currentUserId, mode);
      return true;
    } catch (e) {
      debugPrint('切换模式失败: $e');
      return false;
    }
  }

  // 获取用户所有模式的数据概览
  Future<Map<String, dynamic>> getUserDataOverview() async {
    final overview = <String, dynamic>{};

    try {
      // 获取用户基本信息
      final userInfo = await _dbHelper.queryRows(DatabaseHelper.tableUser, 
          where: {DatabaseHelper.columnUserId: currentUserId});
      
      if (userInfo.isNotEmpty) {
        overview['user'] = userInfo.first;
      }

      // 获取各模式数据概览
      // 1. 经期模式概览
      final periods = await _dbHelper.queryRows(DatabaseHelper.tablePeriod, 
          where: {'user_id': currentUserId}, 
          orderBy: 'start_date DESC');
      
      overview['period'] = {
        'count': periods.length,
        'lastPeriod': periods.isNotEmpty ? periods.first : null,
        'avgCycle': periods.length >= 2 ? _calculateAvgCycle(periods) : null
      };

      // 2. 备孕模式概览
      final bbtRecords = await _dbHelper.queryRows(DatabaseHelper.tableBBTRecords, 
          where: {'user_id': currentUserId});
      
      overview['pregnancyPrep'] = {
        'bbtRecordsCount': bbtRecords.length,
        'cmRecordsCount': await _countRecords(DatabaseHelper.tableCMRecords, {'user_id': currentUserId}),
        'ovulationTestsCount': await _countRecords(DatabaseHelper.tableOvulationTests, {'user_id': currentUserId})
      };

      // 3. 孕期模式概览
      final pregnancyInfo = await _dbHelper.queryRows(DatabaseHelper.tablePregnancy, 
          where: {'user_id': currentUserId});
      
      overview['pregnancy'] = pregnancyInfo.isNotEmpty ? pregnancyInfo.first : null;

      // 4. 育儿模式概览
      final babies = await _dbHelper.queryRows(DatabaseHelper.tableBabyInfo, 
          where: {'user_id': currentUserId});
      
      overview['childcare'] = {
        'babyCount': babies.length,
        'babies': babies
      };
    } catch (e) {
      debugPrint('获取用户数据概览失败: $e');
    }

    return overview;
  }

  // 计算平均周期天数
  int? _calculateAvgCycle(List<Map<String, dynamic>> periods) {
    if (periods.length < 2) return null;

    int totalDays = 0;
    int count = 0;

    for (int i = 0; i < periods.length - 1; i++) {
      final current = DateTime.parse(periods[i]['start_date'] as String);
      final next = DateTime.parse(periods[i + 1]['start_date'] as String);
      final days = next.difference(current).inDays;
      if (days > 15 && days < 40) { // 合理周期范围
        totalDays += days;
        count++;
      }
    }

    return count > 0 ? (totalDays / count).round() : null;
  }

  // 计数辅助方法
  Future<int> _countRecords(String table, Map<String, dynamic> where) async {
    try {
      final db = await _dbHelper.database;
      final List<Map<String, dynamic>> result = await db.rawQuery(
        'SELECT COUNT(*) as count FROM $table WHERE ${where.keys.map((k) => '$k = ?').join(' AND ')}',
        where.values.toList(),
      );
      return Sqflite.firstIntValue(result) ?? 0;
    } catch (e) {
      debugPrint('计数失败 $table: $e');
      return 0;
    }
  }

  // 获取用户设置
  Future<Map<String, String>?> getUserSettings() async {
    return await _dbHelper.getUserSettings(currentUserId);
  }

  // 保存用户设置
  Future<bool> saveUserSettings(Map<String, String> settings) async {
    try {
      await _dbHelper.insertUserSettings(currentUserId, settings);
      return true;
    } catch (e) {
      debugPrint('保存设置失败: $e');
      return false;
    }
  }

  // 获取特定设置项
  Future<String?> getSetting(String key) async {
    final settings = await getUserSettings();
    return settings?[key];
  }

  // 保存特定设置项
  Future<bool> saveSetting(String key, String value) async {
    return await saveUserSettings({key: value});
  }

  // 清除所有模式数据（谨慎使用）
  Future<bool> clearAllData() async {
    try {
      await _dbHelper.transaction((txn) async {
        // 清除各模式数据表
        final tablesToClear = [
          DatabaseHelper.tablePeriod,
          DatabaseHelper.tableSymptom,
          DatabaseHelper.tableBBTRecords,
          DatabaseHelper.tableCMRecords,
          DatabaseHelper.tableOvulationTests,
          DatabaseHelper.tablePregnancy,
          DatabaseHelper.tablePregnancyCheckup,
          DatabaseHelper.tableFetalMovements,
          DatabaseHelper.tableBabyInfo,
          DatabaseHelper.tableBabyGrowth,
          DatabaseHelper.tableVaccine,
          DatabaseHelper.tableFeedingRecords,
          DatabaseHelper.tableSleepRecords,
          DatabaseHelper.tablePhoto
        ];

        for (final table in tablesToClear) {
          await _dbHelper.deleteWhere(table, {'user_id': currentUserId});
        }
      });
      return true;
    } catch (e) {
      debugPrint('清除数据失败: $e');
      return false;
    }
  }

  // 数据转换工具方法
  // 转换日期格式
  String formatDate(DateTime date) {
    return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
  }

  // 转换时间格式
  String formatTime(DateTime time) {
    return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
  }

  // 合并不同模式的数据（例如：从经期模式到备孕模式）
  Future<bool> prepareDataForModeSwitch(String fromMode, String toMode) async {
    try {
      // 从经期模式切换到备孕模式时，复制经期数据到BBT记录表作为初始参考
      if (fromMode == 'period' && toMode == 'pregnancyPrep') {
        final periods = await _dbHelper.queryRows(DatabaseHelper.tablePeriod, 
            where: {'user_id': currentUserId}, 
            orderBy: 'start_date DESC');
        
        // 只取最近三条记录
        final recentPeriods = periods.take(3).toList();
        
        // 记录最近三次经期信息作为备孕参考
        for (final period in recentPeriods) {
          final startDate = period['start_date'] as String;
          await _dbHelper.insert(DatabaseHelper.tableBBTRecords, {
            'user_id': currentUserId,
            'record_date': startDate,
            'temperature': 0.0, // 占位符，表示经期开始
            'notes': '经期开始'
          });
        }
      }
      
      // 从备孕模式切换到孕期模式时，记录怀孕信息
      if (fromMode == 'pregnancyPrep' && toMode == 'pregnancy') {
        final lastPeriod = await _dbHelper.queryRows(
          DatabaseHelper.tablePeriod,
          where: {'user_id': currentUserId},
          orderBy: 'end_date DESC'
        );
        
        if (lastPeriod.isNotEmpty) {
          final lastPeriodDate = DateTime.parse(lastPeriod.first['end_date'] as String);
          final estimatedDueDate = lastPeriodDate.add(Duration(days: 280)); // 预产期计算
          
          await _dbHelper.insert(DatabaseHelper.tablePregnancy, {
            'user_id': currentUserId,
            'last_period_date': lastPeriod.first['end_date'],
            'estimated_due_date': formatDate(estimatedDueDate),
            'conception_date': formatDate(lastPeriodDate.add(Duration(days: 14))), // 估算受孕日期
            'created_at': DateTime.now().toIso8601String()
          });
        }
      }
      
      // 从孕期模式切换到育儿模式时，创建宝宝信息
      if (fromMode == 'pregnancy' && toMode == 'childcare') {
        final pregnancy = await _dbHelper.queryRows(
          DatabaseHelper.tablePregnancy,
          where: {'user_id': currentUserId}
        );
        
        if (pregnancy.isNotEmpty) {
          await _dbHelper.insert(DatabaseHelper.tableBabyInfo, {
            'user_id': currentUserId,
            'name': 'Baby', // 使用英文避免硬编码中文
            'birth_date': formatDate(DateTime.now()), // 这里应该用实际出生日期
            'birth_weight': 3.5, // 占位符
            'birth_height': 50.0, // 占位符
            'delivery_method': 'natural', // 占位符，使用英文
          });
        }
      }
      
      return true;
    } catch (e) {
      debugPrint('模式切换数据准备失败: $e');
      return false;
    }
  }

  // 获取周期性健康报告数据
  Future<Map<String, dynamic>> generateHealthReport({required String startDate, required String endDate}) async {
    final report = <String, dynamic>{};
    
    try {
      // 汇总不同模式的数据
      final periods = await _dbHelper.queryRows(
        DatabaseHelper.tablePeriod,
        where: {
          'user_id': currentUserId,
          'start_date >=': startDate,
          'start_date <=': endDate
        }
      );
      
      final symptoms = await _dbHelper.queryRows(
        DatabaseHelper.tableSymptom,
        where: {
          'user_id': currentUserId,
          'record_date >=': startDate,
          'record_date <=': endDate
        }
      );
      
      report['periods'] = periods;
      report['symptoms'] = symptoms;
      
      // 分析数据
      report['analysis'] = _analyzeHealthData(periods, symptoms);
      
    } catch (e) {
      debugPrint('生成健康报告失败: $e');
    }
    
    return report;
  }

  // 分析健康数据
  Map<String, dynamic> _analyzeHealthData(
      List<Map<String, dynamic>> periods,
      List<Map<String, dynamic>> symptoms) {
    final analysis = <String, dynamic>{};
    
    // 计算平均经期长度
    if (periods.isNotEmpty) {
      int totalDays = 0;
      for (final period in periods) {
        final start = DateTime.parse(period['start_date'] as String);
        final end = DateTime.parse(period['end_date'] as String);
        totalDays += end.difference(start).inDays + 1;
      }
      analysis['avgPeriodLength'] = (totalDays / periods.length).toStringAsFixed(1);
    }
    
    // 分析症状频率
    final symptomFrequency = <String, int>{};
    for (final symptom in symptoms) {
      final type = symptom['symptom_type'] as String;
      symptomFrequency[type] = (symptomFrequency[type] ?? 0) + 1;
    }
    
    // 找出最常见症状
    if (symptomFrequency.isNotEmpty) {
      final mostCommon = symptomFrequency.entries.reduce((a, b) => 
          a.value > b.value ? a : b);
      analysis['mostCommonSymptom'] = mostCommon.key;
    }
    
    return analysis;
  }
}

// 模型转换服务
class ModelConversionService {
  // 通用数据转换方法
  
  // 将数据库Map转换为模型对象（通用方法模板）
  T mapToModel<T>(Map<String, dynamic> map, T Function(Map<String, dynamic>) factoryMethod) {
    try {
      return factoryMethod(map);
    } catch (e) {
      debugPrint('Model conversion error: $e');
      rethrow;
    }
  }

  // 将模型对象转换为数据库Map（通用方法模板）
  Map<String, dynamic> modelToMap<T>(T model, Map<String, dynamic> Function(T) toMapMethod) {
    try {
      return toMapMethod(model);
    } catch (e) {
      debugPrint('Map conversion error: $e');
      rethrow;
    }
  }

  // 批量转换数据库Map列表为模型对象列表
  List<T> mapsToModels<T>(List<Map<String, dynamic>> maps, T Function(Map<String, dynamic>) factoryMethod) {
    return maps.map((map) => mapToModel(map, factoryMethod)).toList();
  }

  // 批量转换模型对象列表为数据库Map列表
  List<Map<String, dynamic>> modelsToMaps<T>(List<T> models, Map<String, dynamic> Function(T) toMapMethod) {
    return models.map((model) => modelToMap(model, toMapMethod)).toList();
  }

  // 数据清理和标准化方法
  
  // 清理字符串值
  String? cleanString(String? value, {String defaultValue = ''}) {
    if (value == null) return defaultValue;
    final cleaned = value.trim();
    return cleaned.isEmpty ? defaultValue : cleaned;
  }

  // 确保数值在有效范围内
  double ensureDoubleRange(double value, double min, double max, {double defaultValue = 0.0}) {
    if (value < min || value > max) return defaultValue;
    return value;
  }

  // 确保整数值在有效范围内
  int ensureIntRange(int value, int min, int max, {int defaultValue = 0}) {
    if (value < min || value > max) return defaultValue;
    return value;
  }

  // 格式化日期字符串
  String formatDateTimeForDatabase(DateTime dateTime) {
    return dateTime.toIso8601String();
  }

  // 解析数据库日期字符串
  DateTime parseDateTimeFromDatabase(String dateTimeStr) {
    try {
      return DateTime.parse(dateTimeStr);
    } catch (e) {
      debugPrint('Date parsing error: $e');
      return DateTime.now();
    }
  }

  // 安全获取布尔值（处理数据库中的整数表示）
  bool safeGetBool(dynamic value, {bool defaultValue = false}) {
    if (value == null) return defaultValue;
    if (value is bool) return value;
    if (value is int) return value == 1;
    if (value is String) return value.toLowerCase() == 'true' || value == '1';
    return defaultValue;
  }

  // 安全获取整数值
  int safeGetInt(dynamic value, {int defaultValue = 0}) {
    if (value == null) return defaultValue;
    if (value is int) return value;
    if (value is double) return value.toInt();
    if (value is String) return int.tryParse(value) ?? defaultValue;
    return defaultValue;
  }

  // 安全获取双精度值
  double safeGetDouble(dynamic value, {double defaultValue = 0.0}) {
    if (value == null) return defaultValue;
    if (value is double) return value;
    if (value is int) return value.toDouble();
    if (value is String) return double.tryParse(value) ?? defaultValue;
    return defaultValue;
  }

  // 处理数据库中的空值
  Map<String, dynamic> removeNullValues(Map<String, dynamic> map) {
    return Map.fromEntries(map.entries.where((entry) => entry.value != null));
  }

  // 合并两个Map，保留非空值
  Map<String, dynamic> mergeMaps(Map<String, dynamic> source, Map<String, dynamic> updates) {
    final result = Map<String, dynamic>.from(source);
    updates.forEach((key, value) {
      if (value != null) {
        result[key] = value;
      }
    });
    return result;
  }

  // 将对象列表序列化（用于JSON存储）
  String serializeList<T>(List<T> items, Map<String, dynamic> Function(T) toMapMethod) {
    final maps = modelsToMaps(items, toMapMethod);
    return '[${maps.map((map) {
      return map.entries.map((entry) {
        if (entry.value is String) {
          return '"${entry.key}": "${entry.value}"';
        } else {
          return '"${entry.key}": ${entry.value}';
        }
      }).join(', ');
    }).join('}, {')}]';
  }
}

// 数据验证服务
class DataValidationService {
  // 验证邮箱格式
  bool isValidEmail(String email) {
    final emailRegex = RegExp(r'^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+');
    return emailRegex.hasMatch(email);
  }

  // 验证手机号码格式（中国大陆）
  bool isValidPhone(String phone) {
    final phoneRegex = RegExp(r'^1[3-9]\d{9}$');
    return phoneRegex.hasMatch(phone);
  }

  // 验证日期是否在合理范围内
  bool isValidDate(String dateStr) {
    try {
      final date = DateTime.parse(dateStr);
      final now = DateTime.now();
      final minDate = now.subtract(Duration(days: 365 * 100)); // 100年前
      final maxDate = now.add(Duration(days: 365)); // 1年后
      return date.isAfter(minDate) && date.isBefore(maxDate);
    } catch (e) {
      return false;
    }
  }

  // 验证基础体温范围
  bool isValidBBT(double temp) {
    return temp >= 35.0 && temp <= 42.0;
  }

  // 验证身高范围（cm）
  bool isValidHeight(int height) {
    return height >= 50 && height <= 250;
  }

  // 验证体重范围（kg）
  bool isValidWeight(double weight) {
    return weight >= 1.0 && weight <= 300.0;
  }
}